package actions;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import utils.MyAutoMergColumnRowProcessor;
import net.sf.jxls.transformer.XLSTransformer;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import exceptions.AppException;

/**
 * 公用的excel导出程序（如果需要动态合并单元格的，则无法用这个Action，参照demo). request set attribute (or
 * session) exceltemplatefile 模板文件名 request set attribute (or session)
 * exceldatamap 模板数据map
 * @author taotao
 */
public class CommonExcelExportAction extends Action {
    /**
     * excel 模板文件名（全路径）
     */
    public static final String EXCEL_TEMPLATE_NAME = "exceltemplatefile";
    /**
     * 导出时（另存为）的文件名
     */
    public static final String EXCEL_FILE_NAME = "excelfile";
    /**
     * excel数据 map
     */
    public static final String EXCEL_DATAMAP_NAME = "exceldatamap";
    /**
     * 自动合并的单元格的column index ，放入的是short 数组，表明自动合并哪些单元格（数值相同的同一列的所有行合并成一行）
     */
    public static final String EXCEL_AUTOMERGECOLUMNS = "excelautomergecolumns";

    /**
     * templateFileName必须是一个完整的绝对路径.
     * @param mapping action mapping
     * @param form action form
     * @param request http request
     * @param response http response
     * @return action forward
     * @throws Exception any exception
     */
    @SuppressWarnings("unchecked")
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        String templateFileName = (String) request
                .getAttribute(EXCEL_TEMPLATE_NAME);
        if (templateFileName == null || templateFileName.equals("")) {
            templateFileName = (String) request.getSession().getAttribute(
                    EXCEL_TEMPLATE_NAME);
        }
        if (templateFileName == null || templateFileName.equals("")) {
            throw new AppException("exceltemplatefile not spelled");
        }
        String fileName = (String) request.getAttribute(EXCEL_FILE_NAME);
        if (fileName == null || fileName.equals("")) {
            fileName = (String) request.getSession().getAttribute(
                    EXCEL_FILE_NAME);
        }
        if (fileName == null) {
            fileName = "文档.xls";
        }
        short[] autoMergeColumns = (short[]) request
                .getAttribute(EXCEL_AUTOMERGECOLUMNS);
        autoMergeColumns = autoMergeColumns == null ? (short[]) request
                .getSession().getAttribute(EXCEL_AUTOMERGECOLUMNS)
                : autoMergeColumns;
        Map<String, Object> dataMap = (Map<String, Object>) request
                .getAttribute(EXCEL_DATAMAP_NAME);
        if (dataMap == null) {
            dataMap = (Map<String, Object>) request.getSession().getAttribute(
                    EXCEL_DATAMAP_NAME);
        }
        if (dataMap == null) {
            throw new AppException("excel data map not spelled");

        }
        response.setHeader("Content-Type", "application/vnd.ms-excel"
                + ";charset=UTF-8");
        response.addHeader("Content-disposition", "filename="
                + new String(fileName.getBytes(), "ISO8859-1"));

        OutputStream outstream = response.getOutputStream();

        doExportExcel(dataMap, templateFileName, outstream, autoMergeColumns);
        return null;
    }

    private void doExportExcel(Map<String, Object> dataMap,
            String templateFileName, OutputStream outstream,
            short[] autoMergeColumns) throws IOException {
        InputStream instream = null;
        try {
            // 获取excel 导出所需的map数据

            instream = new BufferedInputStream(new FileInputStream(
                    templateFileName));
            XLSTransformer transformer = new XLSTransformer();
            HSSFWorkbook workbook = null;
            if (autoMergeColumns == null) {
                workbook = transformer.transformXLS(instream, dataMap);

            } else {
                MyAutoMergColumnRowProcessor mergProcessor = new MyAutoMergColumnRowProcessor(
                        autoMergeColumns);
                transformer.registerRowProcessor(mergProcessor);
                workbook = transformer.transformXLS(instream, dataMap);
                mergProcessor.mergeCells();
            }
            workbook.write(outstream);
        } catch (Exception e) {
            outstream.write(e.toString().getBytes());
        } finally {
            if (instream != null) {
                instream.close();
            }
        }
    }

}